// import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
// import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
// import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
// import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;

// import java.util.ArrayList;
// import java.util.List;

#include "SearchClause.h"
#include "../../../../ast/expr/SQLIdentifierExpr.h"
#include "../../../../ast/statement/SQLSelectOrderByItem.h"
#include "../../visitor/OracleASTVisitor.h"
#include "../../../../../utils/listTran.h"

SearchClause_Type_ptr SearchClause_Type::DEPTH = SearchClause_Type_ptr(new SearchClause_Type(1ULL << 0, make_string_ptr("DEPTH")));
SearchClause_Type_ptr SearchClause_Type::BREADTH = SearchClause_Type_ptr(new SearchClause_Type(1ULL << 1, make_string_ptr("BREADTH")));

SearchClause_Type::SearchClause_Type(uint64_t mask, string_ptr name)
{
  this->mask = mask;
  this->name = name;
}

SearchClause_Type_ptr SearchClause_Type::valueOf(string_ptr name_)
{
  if (name_->c_str() == "DEPTH")
  {
    return SearchClause_Type::DEPTH;
  }
  else if (name_->c_str() == "BREADTH")
  {
    return SearchClause_Type::BREADTH;
  }
  else
  {
    return nullptr;
  }
}

SearchClause::SearchClause()
{
  items = std::make_shared<std::list<SQLSelectOrderByItem_ptr>>();
}
SearchClause_Type_ptr SearchClause::getType()
{
  return type;
}

void SearchClause::setType(SearchClause_Type_ptr type)
{
  this->type = type;
}

SQLSelectOrderByItem_list_ptr SearchClause::getItems()
{
  return items;
}

void SearchClause::addItem(SQLSelectOrderByItem_ptr item)
{
  if (item != nullptr)
  {
    item->setParent(SharedObject(SearchClause));
  }
  this->items->push_back(item);
}

SQLIdentifierExpr_ptr SearchClause::getOrderingColumn()
{
  return orderingColumn;
}

void SearchClause::setOrderingColumn(SQLIdentifierExpr_ptr orderingColumn)
{
  if (orderingColumn != nullptr)
  {
    orderingColumn->setParent(SharedObject(SearchClause));
  }
  this->orderingColumn = orderingColumn;
}

// @Override
void SearchClause::accept0(OracleASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SearchClause)))
  {
    SQLObject_list_ptr tmp1 = ListTran::tran_class<SQLSelectOrderByItem, SQLObject>(items);
    acceptChild(visitor, tmp1);
    acceptChild(visitor, orderingColumn);
  }
  visitor->endVisit(SharedObject(SearchClause));
}

SQLObject_ptr SearchClause::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<SearchClause>(new SearchClause());
  std::shared_ptr<SearchClause> x = std::dynamic_pointer_cast<SearchClause>(clone_tmp);
  // SearchClause x = new SearchClause();

  x->type = type;

  for (SQLSelectOrderByItem_ptr item : *items)
  {
    SQLSelectOrderByItem_ptr item2 = std::dynamic_pointer_cast<SQLSelectOrderByItem>(item->clone());
    item2->setParent(x);
    x->items->push_back(item2);
  }

  if (orderingColumn != nullptr)
  {
    x->setOrderingColumn(std::dynamic_pointer_cast<SQLIdentifierExpr>(orderingColumn->clone()));
  }

  return x;
}
